package com.huahai.aop;

import com.huahai.annotation.AuthCheck;
import com.huahai.exception.BusinessException;
import com.huahai.exception.ErrorCode;
import com.huahai.pojo.entity.User;
import com.huahai.pojo.enums.UserRoleEnums;
import com.huahai.service.UserService;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

/**
 * 鉴权拦截器
 * @author huahai
 */
@Aspect // 切面
@Component
public class AuthInterceptor {

    @Resource
    private UserService userService;

    /**
     * 切面权限拦截器
     * @param joinPoint 切点
     * @param authCheck 注解
     * @return 拦截结果
     */
    @Around("@annotation(authCheck)")
    public Object doInterceptor(ProceedingJoinPoint joinPoint, AuthCheck authCheck) throws Throwable {
        // 1. 获取注解上的角色值
        String mustRole = authCheck.mustRole();
        // 2. 获取当前登录用户
        // 2.1 获取当前请求属性上下文
        RequestAttributes currentRequestAttributes = RequestContextHolder.currentRequestAttributes();
        // 2.2 获取当前请求的request
        HttpServletRequest request = ((ServletRequestAttributes) currentRequestAttributes).getRequest();
        User loginUser = userService.getLoginUser(request);
        // 3. 判断角色值是否存在，不存在直接放行
        UserRoleEnums mustRoleEnum = UserRoleEnums.getEnumsByValue(mustRole);
        if(mustRoleEnum == null){
            return joinPoint.proceed();
        }
        // 4. 存在则进行权限校验
        // 5. 获取当前登录用户的角色
        String userRole = loginUser.getUserRole();
        UserRoleEnums userRoleEnums = UserRoleEnums.getEnumsByValue(userRole);
        if(userRoleEnums == null){
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
        }
        // 6. 如需管理员权限，当前登录用户不是管理员，则拦截
        if(mustRoleEnum.equals(UserRoleEnums.ADMIN) && !userRoleEnums.equals(UserRoleEnums.ADMIN)){
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
        }
        // 7. 放行
        return joinPoint.proceed();
    }
}
